#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define DU double
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define rep(i,x,n) for(int i=(x);i<=(n);i++)
#define nep(i,x,n) for(int i=(x);i>=(n);i--)
using namespace std;
const int N=1e5+10;
int n,m,L,V,d[N],v[N],a[N],p[N];
int posm[N],lm[N],rm[N],lmax[N],rmax[N],f[20][N],lg[N];
int res1,res2;
struct segtree{
	int l,r,v;
}tr[N*4];
inline void pushup(segtree &u,segtree l,segtree r){
	u.v=min(l.v,r.v);
}
inline void build(int u,int l,int r){
	tr[u].l=l,tr[u].r=r;
	if(l==r){
		tr[u].v=0;
		return ;
	}
	int mid=(l+r)>>1;
	build(u<<1,l,mid),build(u<<1|1,mid+1,r);
	pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}
inline void modify(int u,int x,int v){
	if(tr[u].l==tr[u].r){
		tr[u].v=v;
		return ;
	}
	int mid=(tr[u].l+tr[u].r)>>1;
	if(x<=mid) modify(u<<1,x,v);
	else modify(u<<1|1,x,v);
	pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}
inline int query(int u,int l,int r){
	if(l<=tr[u].l&&tr[u].r<=r) return tr[u].v;
	int mid=(tr[u].l+tr[u].r)>>1,res=1e9;
	if(l<=mid) res=min(res,query(u<<1,l,r));
	if(r>mid) res=min(res,query(u<<1|1,l,r));
	return res;
}
inline int read(){
	int s=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		s=(s<<3)+(s<<1)+(ch^48);
		ch=getchar();
	}
	return s*f;
}
inline void print(int x){
	if(x<0){putchar('-');x=-x;}
	if(x>9) print(x/10);
	putchar(x%10+'0');
}
inline int Findpos(int u){
	int l=1,r=m,res=-1;
	while(l<=r){
		int mid=(l+r)>>1;
		if(d[u]<=p[mid]) r=mid-1,res=mid;
		else l=mid+1;
	}
	return res;
}
inline bool check(int x,int y){
	if(v[x]*v[x]+2*a[x]*(p[y]-d[x])>V*V) return 1;
	return 0;
}
inline int Findl(int u){
	int l=posm[u],r=m,res=-1;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(u,mid)) r=mid-1,res=mid;
		else l=mid+1;
	}
	return res;
}
inline int Findr(int u){
	int l=posm[u],r=m,res=-1;
	while(l<=r){
		int mid=(l+r)>>1;
		if(check(u,mid)) l=mid+1,res=mid;
		else r=mid-1;
	}
	return res;
}
inline int Findmaxx(int l,int r){
	if(l>r) return 0;
	int k=lg[r-l+1];
	return max(f[k][l],f[k][r-(1<<k)+1]);
}
inline int Findmv(int u){
	int l=0,r=u-1,res=-1;
	while(l<=r){
		int mid=(l+r)>>1;
		if(Findmaxx(mid+1,u-1)<=mid) r=mid-1,res=mid;
		else l=mid+1;
	}
	return res;
}
inline void Solve(){
	n=read(),m=read(),L=read(),V=read();
	rep(i,1,n) d[i]=read(),v[i]=read(),a[i]=read();
	rep(i,1,m) p[i]=read();
	res1=res2=0;
	rep(i,1,m) lmax[i]=rmax[i]=0;
	rep(i,1,n){
		posm[i]=Findpos(i);
		if(posm[i]==-1){
			lm[i]=rm[i]=-1;
			continue;
		}
		if(a[i]<=0){
			if(check(i,posm[i])){
				lm[i]=posm[i],rm[i]=Findr(i);
			}
			else lm[i]=rm[i]=-1;
		}
		else{
			if(check(i,m)){
				lm[i]=Findl(i),rm[i]=m;
			}
			else lm[i]=rm[i]=-1;
		}
		if(rm[i]!=-1){
			res1++;
			lmax[rm[i]]=max(lmax[rm[i]],lm[i]);
		}
	}
	rep(i,2,m) lg[i]=lg[i>>1]+1;
	rep(i,1,m) f[0][i]=lmax[i];
	for(int j=1;(1<<j)<=m;j++){
		for(int i=1;i+(1<<j)-1<=m;i++){
			f[j][i]=max(f[j-1][i],f[j-1][i+(1<<(j-1))]);
		}
	}
	build(1,0,m);
	rep(i,1,m){
		int y=Findmv(i);
		modify(1,i,query(1,y,i-1)+1);
	}
	rmax[m]=lmax[m];
	nep(i,m-1,0) rmax[i]=max(rmax[i+1],lmax[i]); 
	rep(i,0,m){
		if(rmax[i]<=i) res2=max(res2,m-query(1,i,i));
	}
	print(res1),putchar(' '),print(res2),puts("");
}
int main(){
	freopen("detect.in","r",stdin);
	freopen("detect.out","w",stdout);
	int Tests=read();
	while(Tests--) Solve();
	return 0;
}